1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.solr.internal.csv;
18  
19  import java.io.IOException;
20  import java.io.StringReader;
21  import java.io.StringWriter;
22  import java.util.Arrays;
23  import java.util.Random;
24  
25  import junit.framework.Test;
26  import junit.framework.TestCase;
27  import junit.framework.TestSuite;
28  
29  /**
30   * CSVPrinterTest
31   */
32  public class CSVPrinterTest extends TestCase {
33    
34    String lineSeparator = "\n";
35  
36    public void testPrinter1() throws IOException {
37      StringWriter sw = new StringWriter();
38      CSVPrinter printer = new CSVPrinter(sw, CSVStrategy.DEFAULT_STRATEGY);
39      String[] line1 = {"a", "b"};
40      printer.println(line1);
41      assertEquals("a,b" + lineSeparator, sw.toString());
42    }
43  
44    public void testPrinter2() throws IOException {
45      StringWriter sw = new StringWriter();
46      CSVPrinter printer = new CSVPrinter(sw, CSVStrategy.DEFAULT_STRATEGY);
47      String[] line1 = {"a,b", "b"};
48      printer.println(line1);
49      assertEquals("\"a,b\",b" + lineSeparator, sw.toString());
50    }
51  
52    public void testPrinter3() throws IOException {
53      StringWriter sw = new StringWriter();
54      CSVPrinter printer = new CSVPrinter(sw, CSVStrategy.DEFAULT_STRATEGY);
55      String[] line1 = {"a, b", "b "};
56      printer.println(line1);
57      assertEquals("\"a, b\",\"b \"" + lineSeparator, sw.toString());
58    }
59  
60    public void testExcelPrinter1() throws IOException {
61      StringWriter sw = new StringWriter();
62      CSVPrinter printer = new CSVPrinter(sw, CSVStrategy.EXCEL_STRATEGY);
63      String[] line1 = {"a", "b"};
64      printer.println(line1);
65      assertEquals("a,b" + lineSeparator, sw.toString());
66    }
67  
68    public void testExcelPrinter2() throws IOException {
69      StringWriter sw = new StringWriter();
70      CSVPrinter printer = new CSVPrinter(sw, CSVStrategy.EXCEL_STRATEGY);
71      String[] line1 = {"a,b", "b"};
72      printer.println(line1);
73      assertEquals("\"a,b\",b" + lineSeparator, sw.toString());
74    }
75  
76  
77    
78    public void testRandom() throws Exception {
79      int iter=10000;
80      strategy = CSVStrategy.DEFAULT_STRATEGY;
81      doRandom(iter);
82      strategy = CSVStrategy.EXCEL_STRATEGY;
83      doRandom(iter);
84  
85      // Strategy for MySQL
86      strategy = new CSVStrategy('\t', CSVStrategy.ENCAPSULATOR_DISABLED, CSVStrategy.COMMENTS_DISABLED,'\\',false, false, false, false);
87      doRandom(iter);
88    }
89  
90    Random r = new Random();
91    CSVStrategy strategy;
92  
93    public void doRandom(int iter) throws Exception {
94      for (int i=0; i<iter; i++) {
95        doOneRandom();
96      }
97    }
98  
99    public void doOneRandom() throws Exception {
100     int nLines = r.nextInt(4)+1;
101     int nCol = r.nextInt(3)+1;
102     // nLines=1;nCol=2;
103     String[][] lines = new String[nLines][];
104     for (int i=0; i<nLines; i++) {
105       String[] line = new String[nCol];
106       lines[i] = line;
107       for (int j=0; j<nCol; j++) {
108         line[j] = randStr();
109       }
110     }
111 
112     StringWriter sw = new StringWriter();
113     CSVPrinter printer = new CSVPrinter(sw, strategy);
114 
115     for (int i=0; i<nLines; i++) {
116       // for (int j=0; j<lines[i].length; j++) System.out.println("### VALUE=:" + printable(lines[i][j]));      
117       printer.println(lines[i]);
118     }
119 
120     printer.flush();
121     String result = sw.toString();
122     // System.out.println("### :" + printable(result));
123 
124     StringReader reader = new StringReader(result);
125 
126     CSVParser parser = new CSVParser(reader, strategy);
127     String[][] parseResult = parser.getAllValues();
128 
129     if (!equals(lines, parseResult)) {
130       System.out.println("Printer output :" + printable(result));
131       assertTrue(false);
132     }
133   }
134 
135   public static boolean equals(String[][] a, String[][] b) {
136     if (a.length != b.length) {
137       return false;
138     }
139     for (int i=0; i<a.length; i++) {
140       String[] linea = a[i];
141       String[] lineb = b[i];
142       if (linea.length != lineb.length) {
143         return false;
144       }
145       for (int j=0; j<linea.length; j++) {
146         String aval = linea[j];
147         String bval = lineb[j];
148         if (!aval.equals(bval)) {
149           System.out.println("expected  :" + printable(aval));
150           System.out.println("got       :" + printable(bval));
151           return false;
152         }
153       }
154     }
155     return true;
156   }
157 
158   public static String printable(String s) {
159     StringBuilder sb = new StringBuilder();
160     for (int i=0; i<s.length(); i++) {
161       char ch = s.charAt(i);
162       if (ch<=' ' || ch>=128) {
163         sb.append("(").append((int)ch).append(")");
164       } else {
165         sb.append(ch);
166       }
167     }
168     return sb.toString();
169   }
170 
171   public String randStr() {
172     int sz = r.nextInt(20);
173     // sz = r.nextInt(3);
174     char[] buf = new char[sz];
175     for (int i=0; i<sz; i++) {
176       // stick in special chars with greater frequency
177       char ch;
178       int what = r.nextInt(20);
179       switch (what) {
180         case 0: ch = '\r'; break;
181         case 1: ch = '\n'; break;
182         case 2: ch = '\t'; break;
183         case 3: ch = '\f'; break;
184         case 4: ch = ' ';  break;
185         case 5: ch = ',';  break;
186         case 6: ch = '"';  break;
187         case 7: ch = '\''; break;
188         case 8: ch = '\\'; break;
189         default: ch = (char)r.nextInt(300); break;
190         // default: ch = 'a'; break;
191       }
192       buf[i] = ch;
193     }
194     return new String(buf);
195   }
196 
197 }